import Request from 'luch-request';
import type { HttpRequestConfig, HttpTask } from 'luch-request';
import { handleError } from './handleError';
import { baseUrl, currentEnv, mockUrl } from '~/envConfig';
import { CustomHttpRequestConfig } from '../api';
import { useUserStore } from '@/store';
export const baseHttpConfig: HttpRequestConfig<HttpTask> = {
  baseURL: baseUrl
};

/**
 * 初始化请求
 * @param config - 基础配置
 * @param requestInterceptor - 请求拦截
 * @param responseInterceptor - 响应拦截
 * @returns http - 请求实例
 */

export const initRequest = (
  config: HttpRequestConfig<HttpTask>,
  requestInterceptor: (http: Request) => void,
  responseInterceptor: (http: Request) => void
): Request => {
  const http = new Request();
  http.setConfig(defaultConfig => {
    return { ...defaultConfig, ...config };
  });
  requestInterceptor(http);
  responseInterceptor(http);
  return http;
};

/**
 * 请求拦截器
 * @param http
 */
export const requestInterceptor = (http: Request) => {
  http.interceptors.request.use(
    (config: CustomHttpRequestConfig) => {
      console.log('请求配置', config);
      // 开发环境下需要局部mock 则 修改baseURL 为 mockUrl
      if (currentEnv === 'development') {
        //当前请求mock 为true 时 将请求路径修改为mcok 路径;
        config.custom.mock && (config.baseURL = mockUrl);
      }
      const userStore = useUserStore();
      config.header.Authorization = userStore.getToken();
      config.data = config.data || {};
      return config;
    },
    (
      config // 可使用async await 做异步操作
    ) => Promise.reject(config)
  );
};

let requestQueue = []; // 待重试请求队列
let isRefreshing = false; // 刷新状态锁
/**
 * 响应拦截器
 * @param http
 */
export const responseInterceptor = (http: Request) => {
  http.interceptors.response.use(
    async response => {
      /* 对响应成功做点什么 可使用async await 做异步操作*/
      const { data, statusCode } = response;
      const successCodes = [200, 0];
      const userStore = useUserStore();
      if (data.code === 401 && userStore.getRefreshToken()) {
        if (!isRefreshing) {
          isRefreshing = true;
          try {
            //刷新token
            await userStore.refreshTokenApi();
            http.config.header.Authorization = userStore.getToken();
            // 刷新后重试
            requestQueue.forEach(cb => cb());
            // 清空队列
            requestQueue = [];
          } catch (error) {
            console.log('刷新失败', error);
            // 刷新失败后，清除token
          } finally {
            isRefreshing = false;
          }
        }

        return new Promise(resolve => {
          requestQueue.push(() => {
            resolve(http.request(response.config));
          });
        });
      }

      if (!successCodes.includes(data.code) && statusCode !== 204) {
        return handleError(response);
      }
      return data || {};
    },
    error => handleError(error)
  );
};
